package com.google.code.jtasks.adapters;

import com.google.code.jtasks.connection.TaskRepoId;

/**
 * Instances of this class are used by {@link ITaskSystemAdapter}s to store and retrieve task repository
 * configuration and session data. Instances of this class are thread-safe as long as the objects stored in
 * {@link #setSessionData(Object)} and {@link #setRepositoryData(Object)} are immutable.
 * 
 * @param <R>
 *            the type of repository data object stored in the {@link RepositoryMetadata} instance
 * @param <S>
 *            the type of session data object stored in the {@link RepositoryMetadata} instance
 */
public final class RepositoryMetadata<R, S>
{
	private final TaskRepoId taskRepoId;
	private R repositoryData;
	private S sessionData;

	/**
	 * Constructs a new {@link RepositoryMetadata} instance.
	 * 
	 * @param taskRepoId
	 *            the {@link TaskRepoId} of the task repository that this {@link RepositoryMetadata} is for
	 */
	public RepositoryMetadata(TaskRepoId taskRepoId)
	{
		if (taskRepoId == null)
			throw new IllegalArgumentException("the TaskRepoId may not be null");

		this.taskRepoId = taskRepoId;

		this.repositoryData = null;
		this.sessionData = null;
	}

	/**
	 * Returns the {@link TaskRepoId} of the task repository that this {@link RepositoryMetadata} is for.
	 * 
	 * @return the {@link TaskRepoId} of the task repository that this {@link RepositoryMetadata} is for
	 */
	public TaskRepoId getTaskRepoId()
	{
		return taskRepoId;
	}

	/**
	 * Returns the repository data object stored in this {@link RepositoryMetadata}, or <code>null</code> if
	 * none has been provided. This object should be used to store reasonably static metadata that only needs
	 * to be collected once per task repository.
	 * 
	 * @return the repository data object stored in this {@link RepositoryMetadata}, or <code>null</code> if
	 *         none has been provided
	 */
	public R getRepositoryData()
	{
		return repositoryData;
	}

	/**
	 * Sets the repository configuration object stored in this {@link RepositoryMetadata}.
	 * 
	 * @param repositoryData
	 *            the repository configuration object to store in this {@link RepositoryMetadata}
	 */
	public void setRepositoryData(R repositoryData)
	{
		this.repositoryData = repositoryData;
	}

	/**
	 * Returns the session data object stored in this {@link RepositoryMetadata}, or <code>null</code> if none
	 * has been provided. This object should be used to store transient metadata that needs to be collected
	 * once per task repository session.
	 * 
	 * @return the session data object stored in this {@link RepositoryMetadata}, or <code>null</code> if none
	 *         has been provided
	 */
	public S getSessionData()
	{
		return sessionData;
	}

	/**
	 * Sets the session data object stored in this {@link RepositoryMetadata}.
	 * 
	 * @param sessionData
	 *            the session data object to store in this {@link RepositoryMetadata} the sessionData to set
	 */
	public void setSessionData(S sessionData)
	{
		this.sessionData = sessionData;
	}

}
